package Main
{
	import flash.events.Event;
	import flash.events.ProgressEvent;
	import flash.net.FileReference;
	import flash.net.FileReferenceList;
	import flash.utils.ByteArray;
	
	import mx.controls.Alert;
	
	import singleton.GUIController;

	/**
	 * This class holds FileReference objects for each different type of file used: ATL, Source Metamodel/Model, Target Metamodel
	 * */
	public class FileReferenceHandlers {
		private var controller:GUIController = GUIController.getInstance();
		private static var fileRef:FileReferenceHandlers;
		public var browserATLFile:FileReference, browserSrcMM:FileReferenceList, browserTrgtMM:FileReference, browserSrcModel:FileReference;
		
		
		public function FileReferenceHandlers()	{
			initBrowsers();
		}
		
		public static function getInstance():FileReferenceHandlers {
			if (fileRef == null) {
				fileRef = new FileReferenceHandlers();
			}
			return fileRef;
		}
		
		//Initializes all FileReference objects with their respective methods.
		private function initBrowsers():void {
			//ATL
			browserATLFile = new FileReference();
			browserATLFile.addEventListener(Event.SELECT, browserATLFile_select);
			browserATLFile.addEventListener(ProgressEvent.PROGRESS, progress);
			browserATLFile.addEventListener(Event.COMPLETE, browserATL_complete);
			
			
			//Source Metamodel
			browserSrcMM = new FileReferenceList();
			browserSrcMM.addEventListener(Event.SELECT, browserSrcMM_select);
			//browserSrcMM.addEventListener(ProgressEvent.PROGRESS, progress);
			//browserSrcMM.addEventListener(Event.COMPLETE, browserSrcMM_complete);
			
			//Target Metamodel
			browserTrgtMM = new FileReference();
			browserTrgtMM.addEventListener(Event.SELECT, browserTrgtMM_select);
			browserTrgtMM.addEventListener(ProgressEvent.PROGRESS, progress);
			browserTrgtMM.addEventListener(Event.COMPLETE, browserTrgtMM_complete);
			
			//Source Model
			browserSrcModel = new FileReference();
			browserSrcModel.addEventListener(Event.SELECT, browserSrcModel_select);
			browserSrcModel.addEventListener(ProgressEvent.PROGRESS, progress);
			browserSrcModel.addEventListener(Event.COMPLETE, browserSrcModel_complete);
		}
		
		//Handlers for the select step
		private function browserATLFile_select(evt:Event):void {
			try {
				browserATLFile.load();
	
			} catch (err:Error) {
				UploadHandler.resetField(GUIController.ATL_FILE);
			}
		}
		
		private function browserSrcMM_select(evt:Event):void {
			try {
				var file:FileReference;
				
				var selectedFileArray:Array = browserSrcMM.fileList;
				
				for (var i:uint = 0; i < selectedFileArray.length; i++)	{
					file = FileReference(selectedFileArray[i]);
					file.addEventListener(ProgressEvent.PROGRESS, progress);
					file.addEventListener(Event.COMPLETE, browserSrcMM_complete);
					file.load();
				}
				controller.getTextInput(GUIController.SRC_METAMODEL).text = "";
				
			} catch (err:Error) {
				UploadHandler.resetField(GUIController.SRC_METAMODEL);
			}
		}
		
		private function browserTrgtMM_select(evt:Event):void {
			try {
				browserTrgtMM.load();
				
				
			} catch (err:Error) {
				UploadHandler.resetField(GUIController.TRGT_METAMODEL);
			}
		}
		
		private function browserSrcModel_select(evt:Event):void {
			try {
				browserSrcModel.load();
				
			} catch (err:Error) {
				
				TransformationHandler.resetModelField();
				
			}
		}
		
		//Handler for the progress step
		private function progress(evt:Event):void {
			if (controller.getCurrentState() == "Uploading") {
				controller.getProgressBar(GUIController.UPLOAD).setVisible(true);
			} else {
				controller.getProgressBar(GUIController.EXECUTE).setVisible(true);
			}
		}
		
		//Handlers for the complete step
		private function browserATL_complete(evt:Event):void {
			UploadHandler.toggleUploadButton(true);
			controller.getProgressBar(GUIController.UPLOAD).setVisible(false);
			controller.getTextInput(GUIController.ATL_FILE).text = browserATLFile.name;
			
			
		}
		
		private function browserSrcMM_complete(evt:Event):void {
			try {

				var file:FileReference;				
				
				file = FileReference(evt.target);
				if (controller.getTextInput(GUIController.SRC_METAMODEL).text == "")
					controller.getTextInput(GUIController.SRC_METAMODEL).text = file.name;
				else
					controller.getTextInput(GUIController.SRC_METAMODEL).text += ", " + file.name;
				
				
				controller.getImage(GUIController.SRC_METAMODEL).setVisible(true);
				if (browserTrgtMM.data != null) {
					UploadHandler.toggleUploadButton(true);
					controller.getAction(GUIController.SHAKE).play();
				}
				
				
			} catch (err:Error) {
				
			}
			controller.getProgressBar(GUIController.UPLOAD).setVisible(false);
			
		}
		
		private function browserTrgtMM_complete(evt:Event):void {
			try {

				
				controller.getTextInput(GUIController.TRGT_METAMODEL).text = browserTrgtMM.name;
				controller.getImage(GUIController.TRGT_METAMODEL).setVisible(true);
				if (FileReference(browserSrcMM.fileList[0]).data != null) {
					
					UploadHandler.toggleUploadButton(true);
					controller.getAction(GUIController.SHAKE).play();
				}				
				
			} catch (err:Error) {
				
			}
			controller.getProgressBar(GUIController.UPLOAD).setVisible(false);
			
		}
		
		private function browserSrcModel_complete(evt:Event):void {
			try {
				controller.getTextInput(GUIController.SRC_MODEL).text = browserSrcModel.name;
				controller.getImage(GUIController.WARN).setVisible(false);
				controller.getImage(GUIController.OK).setVisible(true);
				
				TransformationHandler.toggleExecutionButton(false);
				controller.getAction(GUIController.SHAKE).play();
				
				
				
			} catch (err:Error) {
				
				TransformationHandler.resetModelField();
				controller.getImage(GUIController.WARN).setVisible(true);
				controller.getImage(GUIController.OK).setVisible(false);
			}
			controller.getProgressBar(GUIController.EXECUTE).setVisible(false);
			
		}
		
		//Reload all FileReference objects
		public function clearData(): void {
			initBrowsers();
		}
		
		//Searches for a metamodel name on an ecore metamodel file
		private function searchMetamodelName(name:String, content:String):Boolean {
			var lines:Array = content.split("\n");
			var i:int;
			var insideTag:Boolean = false;
			for (i = 0; i < lines.length; i++) {
				if (lines[i].toString().indexOf("<ecore:EPackage") != -1) {
					insideTag = true;
				}
				if (insideTag) {
					var indexStart:int = lines[i].toString().indexOf('name="');
					if (indexStart == -1) {
						continue;
					}
					var indexEnd:int = indexStart + 'name="'.length;
					var nameFound:String = "";
					while (lines[i].toString().charAt(indexEnd) != '"') {
						nameFound += lines[i].toString().charAt(indexEnd);
						indexEnd++;
					}
					
					if (nameFound.toLowerCase() == name.toLowerCase())
						return true;
					
				}
				if (lines[i].toString().indexOf(">") != -1) {
					insideTag = false;
				}
			}
			return false;
		}
	}
}